<?php
declare(strict_types=1);

namespace App\Service\Pushapp;
use Exception;
use Hyperf\Guzzle\ClientFactory;
use Psr\Log\LoggerInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
/**
 * vivo推送
 */
class VivosService
{
	protected ClientFactory $clientFactory;

    protected LoggerInterface $logger;

    protected $redis;

    /**
     * @var string
     */
    private $api = 'https://api-push.vivo.com.cn/';

    /**
     * @var string
     */
    private $token_cache_key = 'newxhqandroidpush:token:vivo-tocken';

    /**
     * @var string
     */
    private $vivo_lock_key = 'newxhqandroidpush:vivo-lock';

    /**
     * @var mixed
     */
    private $AppID = '';

    /**
     * @var mixed
     */
    private $AppKey = '';

    /**
     * @var mixed
     */
    private $AppSecret = '';

    public function __construct(ClientFactory $clientFactory,LoggerFactory $loggerFactory)
    {
        $this->clientFactory = $clientFactory;
        $this->logger = $loggerFactory->get('log', 'default');
        $container = ApplicationContext::getContainer();
        $this->redis = $container->get(\Hyperf\Redis\Redis::class);
        $config = config('xhqparams.vivo', []);
        $this->AppID =  $config['appId'];
        $this->AppKey =  $config['appKey'];
        $this->AppSecret =  $config['appSecret'];
    }

    public function sPush(array $push_data, string $reg_id)
    {
        
        $data = [
            'regId' => $reg_id,
            "notifyType" => '3',
            "title" => $push_data['title'],
            "content" => $push_data['content'],
            "skipType" => 1,
            "classification" => 1,
            //"pushMode" => 1,//测试模式1
            "requestId" => $this->getRequestId()
        ];
        if (!empty($push_data['extra'])) {
            $data['skipType'] = 4;
            $data['skipContent'] = 'intent://com.vivo.xhqassistant/detail?#Intent;scheme=vpushscheme;component=com.nursegroup.recruitment/.push.vivo.VivoPushActivity;S.PUSH_EXTRA_KEY='.json_encode($push_data['extra']).';end';
        }
        $options = [
            'base_uri' => $this->api,
            'timeout'  => 3.0,
        ];
        $post_guz = [
            'headers' => ['Content-Type' => 'application/json','authToken'=>$this->getTocken()],
            'body' => json_encode($data)
        ];
        
        $resp = $this->clientFactory->create($options)->request('post','message/send',$post_guz);
        $result_body = $resp->getBody()->getContents();
        $res = json_decode($result_body,true);
        if(isset($res['result']) && $res['result']==0){
            return ['status'=>1,'data'=>$res];
        }elseif(isset($res['result']) && $res['result']==10070){
            //当日超过限制不再通知
            //$this->dayLock();
            return ['status'=>0,'data'=>$res];
        }else{
            return ['status'=>0,'data'=>$res];
        }
    }
    /**
     * [getTocken 获取token]
     * @return string
     */
    public function getTocken(): string
    {
        if ($this->redis->exists($this->token_cache_key)) {
            return $this->redis->get($this->token_cache_key);
        }
        $timestamp = $this->getTimeStamp();
        $sign = md5($this->AppID.$this->AppKey.$timestamp.$this->AppSecret);
        $param = [
            'appId'=>$this->AppID,
            'appKey'=>$this->AppKey,
            'timestamp'=>$timestamp,
            'sign'=>$sign,
        ];
        $options = [
            'base_uri' => $this->api,
            'timeout'  => 3.0,
        ];
        $post_guz = [
            'headers' => ['Content-Type' => 'application/json'],
            'body' => json_encode($param)
        ];
        $resp = $this->clientFactory->create($options)->request('post','message/auth',$post_guz);
        $result_body = $resp->getBody()->getContents();
        $res = json_decode($result_body,true);
        if(isset($res) && isset($res['authToken'])){
            $this->redis->set($this->token_cache_key,$res['authToken'],7200);
        }
        return isset($res['authToken'])?$res['authToken']:'';
    }
    /**
     * [getTimeStamp 获取鉴权时间搓]
     * @return float
     */
    private function getTimeStamp(): float
    {
        list($msec, $sec) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }
    /**
     * [getRequestId 获取RequestId]
     * @return string
     */
    public function getRequestId(): string
    {
        return uniqid().time();
    }
}